import { getSheetIndex } from '../methods/get'
import editor from '../global/editor'
import { isRealNull, isEditMode } from '../global/validate'
import tooltip from '../global/tooltip'
import { rowlenByRange } from '../global/getRowlen'
import { selectHightlightShow } from './select'
import { luckysheetMoveEndCell } from './sheetMove'
import { luckysheetlodingHTML } from '../controllers/constant'
import server from './server'
import locale from '../locale/locale'
import Store from '../store'
import menuButton from './menuButton'
import conditionformat from './conditionformat'
import alternateformat from './alternateformat'
import { checkProtectionAuthorityNormal } from './protection'
import { rgbTohex, showrightclickmenu } from '../utils/util'
import cleargridelement from '../global/cleargridelement'
import { jfrefreshgrid, jfrefreshgrid_rhcw } from '../global/refresh'
import { orderbydata, orderbydata1D } from '../global/sort'
import json from '../global/json'
import { update, genarate } from '../global/format'

//筛选配置状态
function labelFilterOptionState(
  $top,
  optionstate,
  rowhidden,
  caljs,
  notSave,
  str,
  edr,
  cindex,
  stc,
  edc
) {
  if (optionstate) {
    $top
      .addClass('luckysheet-filter-options-active')
      .data('rowhidden', JSON.stringify(rowhidden))
      .data('caljs', JSON.stringify(caljs))
      .html(
        '<i class="fa fa-filter luckysheet-mousedown-cancel" aria-hidden="true"></i>'
      )

    if (caljs != null) {
      $top
        .data('byconditionvalue', caljs['value'])
        .data('byconditiontype', caljs['type'])
        .data('byconditiontext', caljs['text'])

      if (caljs['value1'] != null) {
        $top.data('byconditionvalue1', caljs['value1'])
      }

      if (caljs['value2'] != null) {
        $top.data('byconditionvalue2', caljs['value2'])
      }
    }
  } else {
    $top
      .removeClass('luckysheet-filter-options-active')
      .data('rowhidden', '')
      .data('caljs', '')
      .html(
        '<i class="fa fa-caret-down luckysheet-mousedown-cancel" aria-hidden="true"></i>'
      )

    $top
      .data('byconditionvalue', 'null')
      .data('byconditiontype', '0')
      .data('byconditiontext', '无')
      .data('byconditionvalue1', '')
      .data('byconditionvalue2', '')
  }

  if (!!notSave) {
    let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]

    if (file.filter == null) {
      file.filter = {}
    }

    if (optionstate) {
      let param = {
        caljs: caljs,
        rowhidden: rowhidden,
        optionstate: optionstate,
        str: str,
        edr: edr,
        cindex: cindex,
        stc: stc,
        edc: edc,
      }
      file.filter[cindex - stc] = param
    } else {
      delete file.filter[cindex - stc]
    }

    server.saveParam('all', Store.currentSheetIndex, file.filter, {
      k: 'filter',
    })
  }
}

//筛选排序
function orderbydatafiler(str, stc, edr, edc, index, asc) {
  let d = editor.deepCopyFlowData(Store.flowdata)

  str = str + 1

  let hasMc = false //排序选区是否有合并单元格
  let data = []

  for (let r = str; r <= edr; r++) {
    let data_row = []

    for (let c = stc; c <= edc; c++) {
      if (d[r][c] != null && d[r][c].mc != null) {
        hasMc = true
        break
      }

      data_row.push(d[r][c])
    }

    data.push(data_row)
  }

  if (hasMc) {
    const locale_filter = locale().filter

    if (isEditMode()) {
      alert(locale_filter.mergeError)
    } else {
      tooltip.info(locale_filter.mergeError, '')
    }

    return
  }

  data = orderbydata(data, index - stc, asc)

  for (let r = str; r <= edr; r++) {
    for (let c = stc; c <= edc; c++) {
      d[r][c] = data[r - str][c - stc]
    }
  }

  let allParam = {}
  if (Store.config['rowlen'] != null) {
    let cfg = $.extend(true, {}, Store.config)
    cfg = rowlenByRange(d, str, edr, cfg)

    allParam = {
      cfg: cfg,
      RowlChange: true,
    }
  }

  jfrefreshgrid(d, [{ row: [str, edr], column: [stc, edc] }], allParam)
}

//创建筛选按钮
function createFilter() {
  if (!checkProtectionAuthorityNormal(Store.currentSheetIndex, 'filter')) {
    return
  }

  if (Store.luckysheet_select_save.length > 1) {
    $('#luckysheet-rightclick-menu').hide()
    $('#luckysheet-filter-menu, #luckysheet-filter-submenu').hide()
    $('#' + Store.container)
      .attr('tabindex', 0)
      .focus()

    const locale_splitText = locale().splitText

    if (isEditMode()) {
      alert(locale_splitText.tipNoMulti)
    } else {
      tooltip.info(locale_splitText.tipNoMulti, '')
    }

    return
  }

  if (
    Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].isPivotTable
  ) {
    return
  }

  $(
    '#luckysheet-filter-selected-sheet' +
      Store.currentSheetIndex +
      ', #luckysheet-filter-options-sheet' +
      Store.currentSheetIndex
  ).remove()

  let last = Store.luckysheet_select_save[0]
  if (
    last['row'][0] == last['row'][1] &&
    last['column'][0] == last['column'][1]
  ) {
    let st_c,
      ed_c,
      curR = last['row'][1]

    for (let c = 0; c < Store.flowdata[curR].length; c++) {
      let cell = Store.flowdata[curR][c]

      if (cell != null && !isRealNull(cell.v)) {
        if (st_c == null) {
          st_c = c
        }
      } else if (st_c != null) {
        ed_c = c - 1
        break
      }
    }

    if (ed_c == null) {
      ed_c = Store.flowdata[curR].length - 1
    }

    Store.luckysheet_select_save = [{ row: [curR, curR], column: [st_c, ed_c] }]
    selectHightlightShow()

    Store.luckysheet_shiftpositon = $.extend(true, {}, last)
    luckysheetMoveEndCell('down', 'range')
  } else if (last['row'][1] - last['row'][0] < 2) {
    Store.luckysheet_shiftpositon = $.extend(true, {}, last)
    luckysheetMoveEndCell('down', 'range')
  }

  Store.luckysheet_filter_save = $.extend(
    true,
    {},
    Store.luckysheet_select_save[0]
  )

  createFilterOptions(Store.luckysheet_filter_save)

  server.saveParam(
    'all',
    Store.currentSheetIndex,
    Store.luckysheet_filter_save,
    { k: 'filter_select' }
  )

  if (Store.filterchage) {
    Store.jfredo.push({
      type: 'filtershow',
      data: [],
      curdata: [],
      sheetIndex: Store.currentSheetIndex,
      filter_save: Store.luckysheet_filter_save,
    })
  }
}

//创建筛选配置
function createFilterOptions(luckysheet_filter_save, filterObj) {
  $('#luckysheet-filter-selected-sheet' + Store.currentSheetIndex).remove()
  $('#luckysheet-filter-options-sheet' + Store.currentSheetIndex).remove()

  if (
    luckysheet_filter_save == null ||
    JSON.stringify(luckysheet_filter_save) == '{}'
  ) {
    return
  }

  let r1 = luckysheet_filter_save.row[0],
    r2 = luckysheet_filter_save.row[1]
  let c1 = luckysheet_filter_save.column[0],
    c2 = luckysheet_filter_save.column[1]

  let row = Store.visibledatarow[r2],
    row_pre = r1 - 1 == -1 ? 0 : Store.visibledatarow[r1 - 1]
  let col = Store.visibledatacolumn[c2],
    col_pre = c1 - 1 == -1 ? 0 : Store.visibledatacolumn[c1 - 1]

  let newSelectedHTML =
    '<div id="luckysheet-filter-selected-sheet' +
    Store.currentSheetIndex +
    '" class="luckysheet-cell-selected luckysheet-filter-selected"  style="left:' +
    col_pre +
    'px;width:' +
    (col - col_pre - 1) +
    'px;top:' +
    row_pre +
    'px;height:' +
    (row - row_pre - 1) +
    'px;display:block;border-color:#897BFF;z-index:3020;background:none;"></div>'
  $('#luckysheet-cell-main').append(newSelectedHTML)

  let optionHTML = ''

  for (let c = c1; c <= c2; c++) {
    if (filterObj == null || filterObj[c - c1] == null) {
      optionHTML +=
        '<div data-rowhidden="" data-str="' +
        r1 +
        '" data-edr="' +
        r2 +
        '" data-cindex="' +
        c +
        '" data-stc="' +
        c1 +
        '" data-edc="' +
        c2 +
        '" class="luckysheet-filter-options" style="left:' +
        (Store.visibledatacolumn[c] - 20) +
        'px;top:' +
        row_pre +
        'px;display:block;"><i class="fa fa-caret-down" aria-hidden="true"></i></div>'
    } else {
      let caljs_data

      if (filterObj[c - c1].caljs != null) {
        let caljs_value1_data
        if (filterObj[c - c1].caljs['value1'] != null) {
          caljs_value1_data =
            'data-byconditionvalue1="' +
            filterObj[c - c1].caljs['value1'] +
            '" '
        } else {
          caljs_value1_data = ''
        }

        let caljs_value2_data
        if (filterObj[c - c1].caljs['value2'] != null) {
          caljs_value2_data =
            'data-byconditionvalue2="' +
            filterObj[c - c1].caljs['value2'] +
            '" '
        } else {
          caljs_value2_data = ''
        }

        caljs_data =
          'data-caljs="' +
          JSON.stringify(filterObj[c - c1].caljs) +
          '" ' +
          'data-byconditionvalue="' +
          filterObj[c - c1].caljs['value'] +
          '" ' +
          'data-byconditiontype="' +
          filterObj[c - c1].caljs['type'] +
          '" ' +
          'data-byconditiontext="' +
          filterObj[c - c1].caljs['text'] +
          '" ' +
          caljs_value1_data +
          caljs_value2_data
      } else {
        caljs_data = ''
      }

      optionHTML +=
        '<div data-rowhidden="' +
        JSON.stringify(filterObj[c - c1].rowhidden).replace(/\"/g, "'") +
        '" ' +
        caljs_data +
        ' data-str="' +
        r1 +
        '" data-edr="' +
        r2 +
        '" data-cindex="' +
        c +
        '" data-stc="' +
        c1 +
        '" data-edc="' +
        c2 +
        '" class="luckysheet-filter-options luckysheet-filter-options-active" style="left:' +
        (Store.visibledatacolumn[c] - 20) +
        'px;top:' +
        row_pre +
        'px;display:block;"><i class="fa fa-filter luckysheet-mousedown-cancel" aria-hidden="true"></i></div>'
    }
  }

  $('#luckysheet-cell-main').append(
    '<div id="luckysheet-filter-options-sheet' +
      Store.currentSheetIndex +
      '" class="luckysheet-filter-options-c">' +
      optionHTML +
      '</div>'
  )
  $('#luckysheet-rightclick-menu').hide()
  $('#luckysheet-filter-menu, #luckysheet-filter-submenu').hide()

  if (
    $('#luckysheet-cell-main').scrollTop() > luckysheet_filter_save['top_move']
  ) {
    $('#luckysheet-scrollbar-y').scrollTop(luckysheet_filter_save['top_move'])
  }

  let file = Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)]

  file.filter_select = luckysheet_filter_save
}

function initialFilterHandler() {
  //filter event handler
  let hidefilersubmenu = null
  const _locale = locale()
  const locale_filter = _locale.filter
  const locale_button = _locale.button
  $('#luckysheetfilter').click(createFilter)

  //右键菜单 菜单项hover
  let submenuhide = null,
    rightclickmenu = null
  $('.luckysheet-cols-menu .luckysheet-cols-submenu').hover(
    function() {
      let $t = $(this),
        attrid = $t.attr('id'),
        $attr = $('#' + attrid + '_sub'),
        $con = $t.parent()
      let winW = $(window).width(),
        winH = $(window).height()
      let menuW = $con.width(),
        attrH = $attr.height() + 25,
        attrW = $attr.width() + 5
      let offset = $t.offset()
      let top = offset.top,
        left = offset.left + menuW

      if (left + attrW > winW) {
        left = offset.left - attrW
      }

      if (top + attrH > winH) {
        top = winH - attrH
      }

      $attr.css({ top: top, left: left }).show()
      rightclickmenu = $t
    },
    function() {
      let $t = $(this),
        attrid = $t.attr('id'),
        $attr = $('#' + attrid + '_sub')
      submenuhide = setTimeout(function() {
        $attr.hide()
      }, 200)
    }
  )

  $('.luckysheet-rightgclick-menu-sub').hover(
    function() {
      rightclickmenu.addClass('luckysheet-cols-menuitem-hover')
      clearTimeout(submenuhide)
    },
    function() {
      rightclickmenu.removeClass('luckysheet-cols-menuitem-hover')
      $(this).hide()
    }
  )

  $('#luckysheet-filter-menu').mouseover(function() {
    clearTimeout(hidefilersubmenu)

    hidefilersubmenu = setTimeout(function() {
      $('#luckysheet-filter-submenu').hide()
    }, 500)
  })

  $('#luckysheet-filter-submenu')
    .mouseover(function() {
      clearTimeout(hidefilersubmenu)
    })
    .find('.luckysheet-cols-menuitem')
    .click(function(e) {
      $('#luckysheet-filter-selected span')
        .html(
          $(this)
            .find('.luckysheet-cols-menuitem-content')
            .text()
        )
        .data('value', $(this).data('value'))
      $('#luckysheet-filter-menu .luckysheet-filter-selected-input').hide()

      let $type = $(this).data('type')
      let $value = $(this).attr('data-value')

      if ($type == '2') {
        $('#luckysheet-filter-selected span').data('type', '2')
        $('#luckysheet-filter-menu .luckysheet-filter-selected-input2').show()
        $(
          '#luckysheet-filter-menu .luckysheet-filter-selected-input input'
        ).prop('type', 'number')
      } else if ($type == '0') {
        $('#luckysheet-filter-selected span').data('type', '0')
      } else {
        $('#luckysheet-filter-selected span').data('type', '1')
        $('#luckysheet-filter-menu .luckysheet-filter-selected-input')
          .eq(0)
          .show()

        //若是日期 改变input type类型为date
        if (
          $value == 'dateequal' ||
          $value == 'datelessthan' ||
          $value == 'datemorethan'
        ) {
          $(
            '#luckysheet-filter-menu .luckysheet-filter-selected-input input'
          ).prop('type', 'date')
        } else if (
          $value == 'morethan' ||
          $value == 'moreequalthan' ||
          $value == 'lessthan' ||
          $value == 'lessequalthan' ||
          $value == 'equal' ||
          $value == 'noequal'
        ) {
          $(
            '#luckysheet-filter-menu .luckysheet-filter-selected-input input'
          ).prop('type', 'number')
        } else {
          $(
            '#luckysheet-filter-menu .luckysheet-filter-selected-input input'
          ).prop('type', 'text')
        }
      }

      $('#luckysheet-filter-byvalue')
        .next()
        .slideUp()
      $('#luckysheet-filter-submenu').hide()
    })

  $('#luckysheet-filter-bycondition, #luckysheet-filter-byvalue').click(
    function() {
      let $t = $(this)
      $t.next().slideToggle(200)

      setTimeout(function() {
        if (
          $t.attr('id') == 'luckysheet-filter-bycondition' &&
          $('#luckysheet-filter-bycondition')
            .next()
            .is(':visible')
        ) {
          if (
            $('#luckysheet-filter-selected span').text() !=
            locale_filter.filiterInputNone
          ) {
            $('#luckysheet-filter-byvalue')
              .next()
              .slideUp(200)
          }
        }

        if ($t.is($('#luckysheet-filter-bycondition'))) {
          if (
            $('#luckysheet-filter-bycondition')
              .next()
              .is(':hidden') &&
            $('#luckysheet-filter-byvalue')
              .next()
              .is(':hidden')
          ) {
            $('#luckysheet-filter-byvalue')
              .next()
              .slideDown(200)
          }
        }
      }, 300)
    }
  )

  $('#luckysheet-filter-selected').click(function() {
    let $t = $(this),
      toffset = $t.offset(),
      $menu = $('#luckysheet-filter-submenu')
    $menu.hide()

    let winH = $(window).height(),
      winW = $(window).width()
    let menuW = $menu.width(),
      menuH = $menu.height()
    let top = toffset.top,
      left = toffset.left,
      mheight = winH - toffset.top - 20

    if (toffset.left + menuW > winW) {
      left = toffset.left - menuW
    }

    if (toffset.top > winH / 2) {
      top = winH - toffset.top

      if (top < 0) {
        top = 0
      }

      mheight = toffset.top - 20
    }

    $menu.css({ top: top, left: left, height: mheight }).show()
    clearTimeout(hidefilersubmenu)
  })

  //筛选按钮点击事件
  $('#luckysheet-cell-main').on('click', '.luckysheet-filter-options', function(
    e
  ) {
    if (!checkProtectionAuthorityNormal(Store.currentSheetIndex, 'filter')) {
      return
    }
    let $t = $(e.currentTarget),
      toffset = $t.offset(),
      $menu = $('#luckysheet-filter-menu'),
      winH = $(window).height(),
      winW = $(window).width()

    let st_r = $t.data('str'),
      ed_r = $t.data('edr'),
      cindex = $t.data('cindex'),
      st_c = $t.data('stc'),
      ed_c = $t.data('edc'),
      rowhidden =
        $t.data('rowhidden') == ''
          ? {}
          : JSON.parse($t.data('rowhidden').replace(/\'/g, '"'))

    $('body .luckysheet-cols-menu').hide()
    $('#luckysheet-filter-menu, #luckysheet-filter-submenu').hide()
    $('#luckysheet-filter-byvalue-input').val('')
    $('#luckysheet-filter-bycondition')
      .next()
      .hide()
    $('#luckysheet-filter-byvalue')
      .next()
      .show()

    $menu.data('str', st_r)
    $menu.data('edr', ed_r)
    $menu.data('cindex', cindex)
    $menu.data('stc', st_c)
    $menu.data('edc', ed_c)

    $('#luckysheet-filter-menu .luckysheet-filter-selected-input')
      .hide()
      .find('input')
      .val()
    $('#luckysheet-filter-selected span')
      .data('type', '0')
      .data('type', null)
      .text(locale_filter.filiterInputNone)

    let byconditiontype = $t.data('byconditiontype')
    $('#luckysheet-filter-selected span')
      .data('value', $t.data('byconditionvalue'))
      .data('type', byconditiontype)
      .text($t.data('byconditiontext'))

    if (byconditiontype == '2') {
      let $input = $(
        '#luckysheet-filter-menu .luckysheet-filter-selected-input2'
      )
        .show()
        .find('input')
      $input.eq(0).val($t.data('byconditionvalue1'))
      $input.eq(1).val($t.data('byconditionvalue2'))
    } else if (byconditiontype == '1') {
      $('#luckysheet-filter-menu .luckysheet-filter-selected-input')
        .eq(0)
        .show()
        .find('input')
        .val($t.data('byconditionvalue1'))
    }

    $('#luckysheet-filter-orderby-asc')
      .off('click')
      .on('click', function() {
        orderbydatafiler(st_r, st_c, ed_r, ed_c, cindex, true)
      })

    $('#luckysheet-filter-orderby-desc')
      .off('click')
      .on('click', function() {
        orderbydatafiler(st_r, st_c, ed_r, ed_c, cindex, false)
      })

    const loadingObj = luckysheetlodingHTML(
      '#luckysheet-filter-byvalue-select',
      { text: locale_filter.filiterMoreDataTip }
    )
    $('#luckysheet-filter-byvalue-select')
      .empty()
      .append(loadingObj.el)

    let rowhiddenother = {} //其它筛选列的隐藏行
    $(
      '#luckysheet-filter-options-sheet' +
        Store.currentSheetIndex +
        ' .luckysheet-filter-options'
    )
      .not(this)
      .each(function() {
        let $t = $(this),
          rh = $t.data('rowhidden')

        if (rh == '') {
          return true
        }

        rh = JSON.parse(rh.replace(/\'/g, '"'))

        for (let r in rh) {
          rowhiddenother[r] = 0
        }
      })

    let data = Store.flowdata

    setTimeout(function() {
      //日期值
      let dvmap = {}
      let dvmap_uncheck = {}

      //除日期以外的值
      let vmap = {}
      let vmap_uncheck = {}

      for (let r = st_r + 1; r <= ed_r; r++) {
        if (r in rowhiddenother) {
          continue
        }

        if (Store.flowdata[r] == null) {
          continue
        }

        let cell = Store.flowdata[r][cindex]

        if (
          cell != null &&
          !isRealNull(cell.v) &&
          cell.ct != null &&
          cell.ct.t == 'd'
        ) {
          //单元格是日期
          let v = update('YYYY-MM-DD', cell.v)

          let y = v.split('-')[0]
          let m = v.split('-')[1]
          let d = v.split('-')[2]

          if (!(y in dvmap)) {
            dvmap[y] = {}
          }

          if (!(m in dvmap[y])) {
            dvmap[y][m] = {}
          }

          if (!(d in dvmap[y][m])) {
            dvmap[y][m][d] = 0
          }

          dvmap[y][m][d]++

          if (r in rowhidden) {
            dvmap_uncheck[y] = 0
            dvmap_uncheck[m] = 0
            dvmap_uncheck[d] = 0
          }
        } else {
          let v, m
          if (cell == null || isRealNull(cell.v)) {
            v = null
            m = null
          } else {
            v = cell.v
            m = cell.m
          }

          if (!(v in vmap)) {
            vmap[v] = {}
          }

          if (!(m in vmap[v])) {
            vmap[v][m] = 0
          }

          vmap[v][m]++

          if (r in rowhidden) {
            vmap_uncheck[v + '#$$$#' + m] = 0
          }
        }
      }

      //遍历数据加到页面
      let item = []

      if (JSON.stringify(dvmap).length > 2) {
        for (let y in dvmap) {
          let ysum = 0
          let monthHtml = ''

          for (let m in dvmap[y]) {
            let msum = 0
            let dayHtml = ''

            for (let d in dvmap[y][m]) {
              let dayL = dvmap[y][m][d]
              msum += dayL

              //月 小于 10
              let mT
              if (Number(m) < 10) {
                mT = '0' + Number(m)
              } else {
                mT = m
              }

              //日 小于 10
              let dT
              if (Number(d) < 10) {
                dT = '0' + Number(d)
              } else {
                dT = d
              }

              //日是否选中状态
              if (
                y in dvmap_uncheck &&
                m in dvmap_uncheck &&
                d in dvmap_uncheck
              ) {
                dayHtml +=
                  '<div class="day luckysheet-mousedown-cancel cf" data-check="false" title="' +
                  y +
                  '-' +
                  mT +
                  '-' +
                  dT +
                  '">' +
                  '<input class="luckysheet-mousedown-cancel" type="checkbox"/>' +
                  '<label class="luckysheet-mousedown-cancel">' +
                  d +
                  '</label>' +
                  '<span class="count luckysheet-mousedown-cancel">( ' +
                  dayL +
                  ' )</span>' +
                  '</div>'
              } else {
                dayHtml +=
                  '<div class="day luckysheet-mousedown-cancel cf" data-check="true" title="' +
                  y +
                  '-' +
                  mT +
                  '-' +
                  dT +
                  '">' +
                  '<input class="luckysheet-mousedown-cancel" type="checkbox" checked="checked"/>' +
                  '<label class="luckysheet-mousedown-cancel">' +
                  d +
                  '</label>' +
                  '<span class="count luckysheet-mousedown-cancel">( ' +
                  dayL +
                  ' )</span>' +
                  '</div>'
              }
            }

            ysum += msum

            //月 小于 10
            let mT2
            if (Number(m) < 10) {
              mT2 = '0' + Number(m)
            } else {
              mT2 = m
            }

            //月是否选中状态
            if (y in dvmap_uncheck && m in dvmap_uncheck) {
              monthHtml +=
                '<div class="monthBox luckysheet-mousedown-cancel">' +
                '<div class="month luckysheet-mousedown-cancel cf" data-check="false" title="' +
                y +
                '-' +
                mT2 +
                '">' +
                '<i class="fa fa-caret-right luckysheet-mousedown-cancel" aria-hidden="true"></i>' +
                '<input class="luckysheet-mousedown-cancel" type="checkbox"/>' +
                '<label class="luckysheet-mousedown-cancel">' +
                m +
                '' +
                locale_filter.filiterMonthText +
                '</label>' +
                '<span class="count luckysheet-mousedown-cancel">( ' +
                msum +
                ' )</span>' +
                '</div>' +
                '<div class="dayList luckysheet-mousedown-cancel">' +
                dayHtml +
                '</div>' +
                '</div>'
            } else {
              monthHtml +=
                '<div class="monthBox luckysheet-mousedown-cancel">' +
                '<div class="month luckysheet-mousedown-cancel cf" data-check="true" title="' +
                y +
                '-' +
                mT2 +
                '">' +
                '<i class="fa fa-caret-right luckysheet-mousedown-cancel" aria-hidden="true"></i>' +
                '<input class="luckysheet-mousedown-cancel" type="checkbox" checked="checked"/>' +
                '<label class="luckysheet-mousedown-cancel">' +
                m +
                '' +
                locale_filter.filiterMonthText +
                '</label>' +
                '<span class="count luckysheet-mousedown-cancel">( ' +
                msum +
                ' )</span>' +
                '</div>' +
                '<div class="dayList luckysheet-mousedown-cancel">' +
                dayHtml +
                '</div>' +
                '</div>'
            }
          }

          //年是否选中状态
          let yearHtml
          if (y in dvmap_uncheck) {
            yearHtml =
              '<div class="yearBox luckysheet-mousedown-cancel">' +
              '<div class="year luckysheet-mousedown-cancel cf" data-check="false" title="' +
              y +
              '">' +
              '<i class="fa fa-caret-right luckysheet-mousedown-cancel" aria-hidden="true"></i>' +
              '<input class="luckysheet-mousedown-cancel" type="checkbox"/>' +
              '<label class="luckysheet-mousedown-cancel">' +
              y +
              '' +
              locale_filter.filiterYearText +
              '</label>' +
              '<span class="count luckysheet-mousedown-cancel">( ' +
              ysum +
              ' )</span>' +
              '</div>' +
              '<div class="monthList luckysheet-mousedown-cancel">' +
              monthHtml +
              '</div>' +
              '</div>'
          } else {
            yearHtml =
              '<div class="yearBox luckysheet-mousedown-cancel">' +
              '<div class="year luckysheet-mousedown-cancel cf" data-check="true" title="' +
              y +
              '">' +
              '<i class="fa fa-caret-right luckysheet-mousedown-cancel" aria-hidden="true"></i>' +
              '<input class="luckysheet-mousedown-cancel" type="checkbox" checked="checked"/>' +
              '<label class="luckysheet-mousedown-cancel">' +
              y +
              '' +
              locale_filter.filiterYearText +
              '</label>' +
              '<span class="count luckysheet-mousedown-cancel">( ' +
              ysum +
              ' )</span>' +
              '</div>' +
              '<div class="monthList luckysheet-mousedown-cancel">' +
              monthHtml +
              '</div>' +
              '</div>'
          }

          item.unshift(yearHtml)
        }
      }

      if (JSON.stringify(vmap).length > 2) {
        let vmapKeys = Object.keys(vmap)
        vmapKeys = orderbydata1D(vmapKeys, true)

        for (let i = 0; i < vmapKeys.length; i++) {
          let v = vmapKeys[i]

          for (let x in vmap[v]) {
            let text
            if (v + '#$$$#' + x == 'null#$$$#null') {
              text = locale_filter.valueBlank
            } else {
              text = x
            }

            //是否选中状态
            let dataHtml
            if (v + '#$$$#' + x in vmap_uncheck) {
              dataHtml =
                '<div class="textBox luckysheet-mousedown-cancel cf" data-check="false" data-filter="' +
                (v + '#$$$#' + x) +
                '" title="' +
                text +
                '">' +
                '<input class="luckysheet-mousedown-cancel" type="checkbox"/>' +
                '<label class="luckysheet-mousedown-cancel">' +
                text +
                '</label>' +
                '<span class="luckysheet-mousedown-cancel count">( ' +
                vmap[v][x] +
                ' )</span>' +
                '</div>'
            } else {
              dataHtml =
                '<div class="textBox luckysheet-mousedown-cancel cf" data-check="true" data-filter="' +
                (v + '#$$$#' + x) +
                '" title="' +
                text +
                '">' +
                '<input class="luckysheet-mousedown-cancel" type="checkbox" checked="checked"/>' +
                '<label class="luckysheet-mousedown-cancel">' +
                text +
                '</label>' +
                '<span class="luckysheet-mousedown-cancel count">( ' +
                vmap[v][x] +
                ' )</span>' +
                '</div>'
            }

            item.push(dataHtml)
          }
        }
      }

      // 适配小屏设备
      let containerH = winH - toffset.top - 350
      if (containerH < 0) containerH = 100
      //$("#luckysheet-filter-byvalue-select").html("<div class='ListBox luckysheet-mousedown-cancel' style='min-height: 100px; max-height: " + containerH + "px; overflow-y: auto; overflow-x: hidden;'><table cellspacing='0' style='width:100%;' class='luckysheet-mousedown-cancel'>" + item.join("") + "</table></div>");

      $('#luckysheet-filter-byvalue-select').append(
        "<div class='ListBox luckysheet-mousedown-cancel' style='min-height: 100px; max-height: " +
          containerH +
          "px; overflow-y: auto; overflow-x: hidden;'><table cellspacing='0' style='width:100%;' class='luckysheet-mousedown-cancel'>" +
          item.join('') +
          '</table></div>'
      )
      loadingObj.close()
    }, 1)

    showrightclickmenu($menu, toffset.left, toffset.top + 20)

    e.stopPropagation()
    return false
  })

  //按颜色筛选
  $('#luckysheet-filter-orderby-color').hover(
    function() {
      //遍历筛选列颜色
      let $menu = $('#luckysheet-filter-menu')
      let st_r = $menu.data('str'),
        ed_r = $menu.data('edr'),
        cindex = $menu.data('cindex'),
        st_c = $menu.data('stc'),
        ed_c = $menu.data('edc')
      let bgMap = {} //单元格颜色
      let fcMap = {} //字体颜色

      let af_compute = alternateformat.getComputeMap()
      let cf_compute = conditionformat.getComputeMap()

      for (let r = st_r + 1; r <= ed_r; r++) {
        let cell = Store.flowdata[r][cindex]

        //单元格颜色
        let bg = menuButton.checkstatus(Store.flowdata, r, cindex, 'bg')

        if (bg == null) {
          bg = '#ffffff'
        }

        let checksAF = alternateformat.checksAF(r, cindex, af_compute)
        if (checksAF != null) {
          //若单元格有交替颜色
          bg = checksAF[1]
        }

        let checksCF = conditionformat.checksCF(r, cindex, cf_compute)
        if (checksCF != null && checksCF['cellColor'] != null) {
          //若单元格有条件格式
          bg = checksCF['cellColor']
        }

        if (bg.indexOf('rgb') > -1) {
          bg = rgbTohex(bg)
        }

        if (bg.length == 4) {
          bg =
            bg.substr(0, 1) +
            bg.substr(1, 1).repeat(2) +
            bg.substr(2, 1).repeat(2) +
            bg.substr(3, 1).repeat(2)
        }

        //字体颜色
        let fc = menuButton.checkstatus(Store.flowdata, r, cindex, 'fc')

        if (checksAF != null) {
          //若单元格有交替颜色
          fc = checksAF[0]
        }

        if (checksCF != null && checksCF['textColor'] != null) {
          //若单元格有条件格式
          fc = checksCF['textColor']
        }

        if (fc.indexOf('rgb') > -1) {
          fc = rgbTohex(fc)
        }

        if (fc.length == 4) {
          fc =
            fc.substr(0, 1) +
            fc.substr(1, 1).repeat(2) +
            fc.substr(2, 1).repeat(2) +
            fc.substr(3, 1).repeat(2)
        }

        if (
          Store.config != null &&
          Store.config['rowhidden'] != null &&
          r in Store.config['rowhidden']
        ) {
          bgMap[bg] = 1

          if (cell != null && !isRealNull(cell.v)) {
            fcMap[fc] = 1
          }
        } else {
          bgMap[bg] = 0

          if (cell != null && !isRealNull(cell.v)) {
            fcMap[fc] = 0
          }
        }
      }
      //
      let filterBgColorHtml = ''
      if (JSON.stringify(bgMap).length > 2 && Object.keys(bgMap).length > 1) {
        let bgColorItemHtml = ''
        for (let b in bgMap) {
          if (bgMap[b] == 0) {
            bgColorItemHtml +=
              '<div class="item luckysheet-mousedown-cancel"><label class="luckysheet-mousedown-cancel" style="background-color: ' +
              b +
              '" title="' +
              b +
              '"></label><input class="luckysheet-mousedown-cancel" type="checkbox" checked="checked"/></div>'
          } else {
            bgColorItemHtml +=
              '<div class="item luckysheet-mousedown-cancel"><label class="luckysheet-mousedown-cancel" style="background-color: ' +
              b +
              '" title="' +
              b +
              '"></label><input class="luckysheet-mousedown-cancel" type="checkbox"/></div>'
          }
        }
        filterBgColorHtml =
          '<div id="filterBgColor" class="box luckysheet-mousedown-cancel"><div class="title luckysheet-mousedown-cancel">' +
          locale_filter.filiterByColorTip +
          '</div><div style="max-height:128px;overflow:auto;" class="luckysheet-mousedown-cancel">' +
          bgColorItemHtml +
          '</div></div>'
      }

      let filterFcColorHtml = ''
      if (JSON.stringify(fcMap).length > 2 && Object.keys(fcMap).length > 1) {
        let fcColorItemHtml = ''
        for (let f in fcMap) {
          if (fcMap[f] == 0) {
            fcColorItemHtml +=
              '<div class="item luckysheet-mousedown-cancel"><label class="luckysheet-mousedown-cancel" style="background-color: ' +
              f +
              '" title="' +
              f +
              '"></label><input class="luckysheet-mousedown-cancel" type="checkbox" checked="checked"/></div>'
          } else {
            fcColorItemHtml +=
              '<div class="item luckysheet-mousedown-cancel"><label class="luckysheet-mousedown-cancel" style="background-color: ' +
              f +
              '" title="' +
              f +
              '"></label><input class="luckysheet-mousedown-cancel" type="checkbox"/></div>'
          }
        }
        filterFcColorHtml =
          '<div id="filterFcColor" class="box luckysheet-mousedown-cancel"><div class="title luckysheet-mousedown-cancel">' +
          locale_filter.filiterByTextColorTip +
          '</div><div style="max-height:128px;overflow:auto;" class="luckysheet-mousedown-cancel">' +
          fcColorItemHtml +
          '</div></div>'
      }
      //
      let content
      if (filterBgColorHtml == '' && filterFcColorHtml == '') {
        content =
          '<div class="luckysheet-mousedown-cancel" style="padding: 10px 30px;text-align: center;">' +
          locale_filter.filterContainerOneColorTip +
          '</div>'
      } else {
        content =
          filterBgColorHtml +
          filterFcColorHtml +
          '<div class="luckysheet-mousedown-cancel"><button id="luckysheet-filter-orderby-color-confirm" class="btn btn-primary luckysheet-mousedown-cancel" style="margin: 5px 20px;width: 70px;">' +
          locale_button.confirm +
          '</button></div>'
      }
      //颜色筛选子菜单
      $('#luckysheet-filter-orderby-color-submenu').remove()
      $('body')
        .first()
        .append(
          '<div id="luckysheet-filter-orderby-color-submenu" class="luckysheet-cols-menu luckysheet-mousedown-cancel">' +
            content +
            '</div>'
        )
      let $t = $('#luckysheet-filter-orderby-color-submenu').end()
      let $con = $(this).parent()
      let winW = $(window).width(),
        winH = $(window).height()
      let menuW = $con.width(),
        myh = $t.height() + 25,
        myw = $t.width() + 5
      let offset = $(this).offset()
      let top = offset.top,
        left = offset.left + menuW

      if (left + myw > winW) {
        left = offset.left - myw
      }

      if (top + myh > winH) {
        top = winH - myh
      }

      $('#luckysheet-filter-orderby-color-submenu')
        .css({ top: top, left: left })
        .show()
    },
    function() {
      submenuhide = setTimeout(function() {
        $('#luckysheet-filter-orderby-color-submenu').hide()
      }, 200)
    }
  )

  $(document).on(
    'mouseover mouseleave',
    '#luckysheet-filter-orderby-color-submenu',
    function(e) {
      if (e.type === 'mouseover') {
        clearTimeout(submenuhide)
      } else {
        $(this).hide()
      }
    }
  )
  $(document).on(
    'click',
    '#luckysheet-filter-orderby-color-submenu .item label',
    function() {
      $(this)
        .siblings("input[type='checkbox']")
        .click()
    }
  )
  $(document)
    .off('click.orderbyColorConfirm')
    .on(
      'click.orderbyColorConfirm',
      '#luckysheet-filter-orderby-color-submenu #luckysheet-filter-orderby-color-confirm',
      function() {
        let bg_colorMap = {}
        let fc_colorMap = {}

        $('#luckysheet-filter-orderby-color-submenu .item').each(function(
          i,
          e
        ) {
          if (
            $(e)
              .find("input[type='checkbox']")
              .is(':checked')
          ) {
            let color = $(this)
              .find('label')
              .attr('title')
            let $id = $(this)
              .closest('.box')
              .attr('id')

            if ($id == 'filterBgColor') {
              bg_colorMap[color] = 0
            } else if ($id == 'filterFcColor') {
              fc_colorMap[color] = 0
            }
          }
        })

        let bg_filter
        if (
          $('#luckysheet-filter-orderby-color-submenu #filterBgColor').length >
          0
        ) {
          bg_filter = true
        } else {
          bg_filter = false
        }

        let fc_filter
        if (
          $('#luckysheet-filter-orderby-color-submenu #filterFcColor').length >
          0
        ) {
          fc_filter = true
        } else {
          fc_filter = false
        }

        let $menu = $('#luckysheet-filter-menu')
        let st_r = $menu.data('str'),
          ed_r = $menu.data('edr'),
          cindex = $menu.data('cindex'),
          st_c = $menu.data('stc'),
          ed_c = $menu.data('edc')

        let rowhiddenother = {} //其它筛选列的隐藏行
        $(
          '#luckysheet-filter-options-sheet' +
            Store.currentSheetIndex +
            ' .luckysheet-filter-options'
        )
          .not(
            $(
              '#luckysheet-filter-options-sheet' +
                Store.currentSheetIndex +
                ' .luckysheet-filter-options'
            )
              .eq(cindex - st_c)
              .get(0)
          )
          .each(function() {
            let $t = $(this),
              rh = $t.data('rowhidden')

            if (rh == '') {
              return true
            }

            rh = JSON.parse(rh)

            for (let r in rh) {
              rowhiddenother[r] = 0
            }
          })

        let filterdata = {}
        let rowhidden = {}
        let caljs = {}

        let af_compute = alternateformat.getComputeMap()
        let cf_compute = conditionformat.getComputeMap()

        for (let r = st_r + 1; r <= ed_r; r++) {
          if (r in rowhiddenother) {
            continue
          }

          if (Store.flowdata[r] == null) {
            continue
          }

          let cell = Store.flowdata[r][cindex]

          //单元格颜色
          let bg = menuButton.checkstatus(Store.flowdata, r, cindex, 'bg')

          let checksAF = alternateformat.checksAF(r, cindex, af_compute)
          if (checksAF != null) {
            //若单元格有交替颜色
            bg = checksAF[1]
          }

          let checksCF = conditionformat.checksCF(r, cindex, cf_compute)
          if (checksCF != null && checksCF['cellColor'] != null) {
            //若单元格有条件格式
            bg = checksCF['cellColor']
          }

          // bg maybe null
          bg = bg == null ? '#ffffff' : bg

          if (bg.indexOf('rgb') > -1) {
            bg = rgbTohex(bg)
          }

          if (bg.length == 4) {
            bg =
              bg.substr(0, 1) +
              bg.substr(1, 1).repeat(2) +
              bg.substr(2, 1).repeat(2) +
              bg.substr(3, 1).repeat(2)
          }

          //文本颜色
          let fc = menuButton.checkstatus(Store.flowdata, r, cindex, 'fc')

          if (checksAF != null) {
            //若单元格有交替颜色
            fc = checksAF[0]
          }

          if (checksCF != null && checksCF['textColor'] != null) {
            //若单元格有条件格式
            fc = checksCF['textColor']
          }

          if (fc.indexOf('rgb') > -1) {
            fc = rgbTohex(fc)
          }

          if (fc.length == 4) {
            fc =
              fc.substr(0, 1) +
              fc.substr(1, 1).repeat(2) +
              fc.substr(2, 1).repeat(2) +
              fc.substr(3, 1).repeat(2)
          }

          if (bg_filter && fc_filter) {
            if (
              !(bg in bg_colorMap) &&
              (!(fc in fc_colorMap) || cell == null || isRealNull(cell.v))
            ) {
              rowhidden[r] = 0
            }
          } else if (bg_filter) {
            if (!(bg in bg_colorMap)) {
              rowhidden[r] = 0
            }
          } else if (fc_filter) {
            if (!(fc in fc_colorMap) || cell == null || isRealNull(cell.v)) {
              rowhidden[r] = 0
            }
          }
        }

        let $top = $(
          '#luckysheet-filter-options-sheet' +
            Store.currentSheetIndex +
            ' .luckysheet-filter-options'
        ).eq(cindex - st_c)

        let optionstate = Object.keys(rowhidden).length > 0

        let rowhiddenall = $.extend(true, rowhiddenother, rowhidden),
          rowhidenPre = json.parseJsonParm($top.data('rowhidden'))

        labelFilterOptionState(
          $top,
          optionstate,
          rowhidden,
          caljs,
          true,
          st_r,
          ed_r,
          cindex,
          st_c,
          ed_c
        )

        let cfg = $.extend(true, {}, Store.config)
        cfg['rowhidden'] = rowhiddenall

        //保存撤销
        if (Store.clearjfundo) {
          let redo = {}
          redo['type'] = 'datachangeAll_filter'
          redo['sheetIndex'] = Store.currentSheetIndex

          redo['config'] = $.extend(true, {}, Store.config)
          redo['curconfig'] = cfg

          redo['optionstate'] = optionstate
          redo['optionsindex'] = cindex - st_c

          redo['rowhidden'] = $.extend(true, {}, rowhidden)
          redo['rowhidenPre'] = $.extend(true, {}, rowhidenPre)

          if (caljs != null) {
            redo['caljs'] = caljs
          }

          Store.jfundo.length = 0
          Store.jfredo.push(redo)
        }

        //config
        Store.config = cfg
        Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config =
          Store.config

        server.saveParam('cg', Store.currentSheetIndex, cfg['rowhidden'], {
          k: 'rowhidden',
        })

        //行高、列宽 刷新
        jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length)

        $(
          '#luckysheet-filter-menu, #luckysheet-filter-submenu, #luckysheet-filter-orderby-color-submenu'
        ).hide()
        cleargridelement()
      }
    )

  //点击复选框
  $(document)
    .off('click.filterCheckbox1')
    .on(
      'click.filterCheckbox1',
      '#luckysheet-filter-byvalue-select .textBox',
      function() {
        if ($(this).attr('data-check') == 'true') {
          $(this).attr('data-check', 'false')
          $(this)
            .find("input[type='checkbox']")
            .removeAttr('checked')
        } else {
          $(this).attr('data-check', 'true')
          $(this)
            .find("input[type='checkbox']")
            .prop('checked', true)
        }
      }
    )
  $(document)
    .off('click.filterCheckbox2')
    .on(
      'click.filterCheckbox2',
      '#luckysheet-filter-byvalue-select .year',
      function() {
        if ($(this).attr('data-check') == 'true') {
          $(this).attr('data-check', 'false')
          $(this)
            .parents('.yearBox')
            .find('.month')
            .attr('data-check', 'false')
          $(this)
            .parents('.yearBox')
            .find('.day')
            .attr('data-check', 'false')
          $(this)
            .parents('.yearBox')
            .find("input[type='checkbox']")
            .removeAttr('checked')
        } else {
          $(this).attr('data-check', 'true')
          $(this)
            .parents('.yearBox')
            .find('.month')
            .attr('data-check', 'true')
          $(this)
            .parents('.yearBox')
            .find('.day')
            .attr('data-check', 'true')
          $(this)
            .parents('.yearBox')
            .find("input[type='checkbox']")
            .prop('checked', true)
        }
      }
    )
  $(document)
    .off('click.filterCheckbox3')
    .on(
      'click.filterCheckbox3',
      '#luckysheet-filter-byvalue-select .month',
      function() {
        //月份 对应的 天
        if ($(this).attr('data-check') == 'true') {
          $(this).attr('data-check', 'false')
          $(this)
            .parents('.monthBox')
            .find('.day')
            .attr('data-check', 'false')
          $(this)
            .parents('.monthBox')
            .find("input[type='checkbox']")
            .removeAttr('checked')
        } else {
          $(this).attr('data-check', 'true')
          $(this)
            .parents('.monthBox')
            .find('.day')
            .attr('data-check', 'true')
          $(this)
            .parents('.monthBox')
            .find("input[type='checkbox']")
            .prop('checked', true)
        }
        //月份 对应的 年份
        let yearDayAllCheck = true
        let $yearDay = $(this)
          .parents('.yearBox')
          .find('.day')
        $yearDay.each(function(i, e) {
          if ($(e).attr('data-check') == 'true') {
          } else {
            yearDayAllCheck = false
          }
        })
        if (yearDayAllCheck) {
          $(this)
            .parents('.yearBox')
            .find('.year')
            .attr('data-check', 'true')
          $(this)
            .parents('.yearBox')
            .find(".year input[type='checkbox']")
            .prop('checked', true)
        } else {
          $(this)
            .parents('.yearBox')
            .find('.year')
            .attr('data-check', 'false')
          $(this)
            .parents('.yearBox')
            .find(".year input[type='checkbox']")
            .removeAttr('checked')
        }
      }
    )
  $(document)
    .off('click.filterCheckbox4')
    .on(
      'click.filterCheckbox4',
      '#luckysheet-filter-byvalue-select .day',
      function() {
        if ($(this).attr('data-check') == 'true') {
          $(this).attr('data-check', 'false')
          $(this)
            .find("input[type='checkbox']")
            .removeAttr('checked')
        } else {
          $(this).attr('data-check', 'true')
          $(this)
            .find("input[type='checkbox']")
            .prop('checked', true)
        }
        //天 对应的 月份
        let monthDayAllCheck = true
        let $monthDay = $(this)
          .parents('.monthBox')
          .find('.day')
        $monthDay.each(function(i, e) {
          if ($(e).attr('data-check') == 'true') {
          } else {
            monthDayAllCheck = false
          }
        })
        if (monthDayAllCheck) {
          $(this)
            .parents('.monthBox')
            .find('.month')
            .attr('data-check', 'true')
          $(this)
            .parents('.monthBox')
            .find(".month input[type='checkbox']")
            .prop('checked', true)
        } else {
          $(this)
            .parents('.monthBox')
            .find('.month')
            .attr('data-check', 'false')
          $(this)
            .parents('.monthBox')
            .find(".month input[type='checkbox']")
            .removeAttr('checked')
        }
        //天 对应的 年份
        let yearDayAllCheck = true
        let $yearDay = $(this)
          .parents('.yearBox')
          .find('.day')
        $yearDay.each(function(i, e) {
          if ($(e).attr('data-check') == 'true') {
          } else {
            yearDayAllCheck = false
          }
        })
        if (yearDayAllCheck) {
          $(this)
            .parents('.yearBox')
            .find('.year')
            .attr('data-check', 'true')
          $(this)
            .parents('.yearBox')
            .find(".year input[type='checkbox']")
            .prop('checked', true)
        } else {
          $(this)
            .parents('.yearBox')
            .find('.year')
            .attr('data-check', 'false')
          $(this)
            .parents('.yearBox')
            .find(".year input[type='checkbox']")
            .removeAttr('checked')
        }
      }
    )

  //日期 三级下拉显示
  $(document)
    .off('click.filterYearDropdown')
    .on(
      'click.filterYearDropdown',
      '#luckysheet-filter-byvalue-select .yearBox .fa-caret-right',
      function(event) {
        let $p = $(this).parents('.luckysheet-mousedown-cancel')
        if ($p.hasClass('year')) {
          $(this)
            .parents('.yearBox')
            .find('.monthList')
            .slideToggle()
        }
        if ($p.hasClass('month')) {
          $(this)
            .parents('.monthBox')
            .find('.dayList')
            .slideToggle()
        }

        event.stopPropagation()
      }
    )

  //全选
  $('#luckysheet-filter-byvalue-btn-all').click(function() {
    $("#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']").prop(
      'checked',
      true
    )
    $("#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']")
      .parents('.luckysheet-mousedown-cancel')
      .attr('data-check', 'true')
  })

  //清除
  $('#luckysheet-filter-byvalue-btn-clear').click(function() {
    $(
      "#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']"
    ).removeAttr('checked')
    $("#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']")
      .parents('.luckysheet-mousedown-cancel')
      .attr('data-check', 'false')
  })

  //反选
  $('#luckysheet-filter-byvalue-btn-contra').click(function() {
    let $input = $(
      "#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']"
    )
    $input.each(function(i, e) {
      if ($(e).is(':checked')) {
        $(e).removeAttr('checked')
        $(e)
          .parents('.luckysheet-mousedown-cancel')
          .attr('data-check', 'false')
      } else {
        $(e).prop('checked', true)
        $(e)
          .parents('.luckysheet-mousedown-cancel')
          .attr('data-check', 'true')
      }
    })
    //天 对应的 月份
    let $month = $('#luckysheet-filter-byvalue-select .ListBox .monthBox')
    $month.each(function(index, event) {
      let monthDayAllCheck = true
      let $monthDay = $(event).find(".day input[type='checkbox']")
      $monthDay.each(function(i, e) {
        if ($(e).is(':checked')) {
        } else {
          monthDayAllCheck = false
        }
      })
      if (monthDayAllCheck) {
        $(event)
          .find(".month input[type='checkbox']")
          .prop('checked', true)
        $(event).attr('data-check', 'true')
      } else {
        $(event)
          .find(".month input[type='checkbox']")
          .removeAttr('checked')
        $(event).attr('data-check', 'false')
      }
    })
    //天 对应的 年份
    let $year = $('#luckysheet-filter-byvalue-select .ListBox .yearBox')
    $year.each(function(index, event) {
      let yearDayAllCheck = true
      let $yearDay = $(event).find(".day input[type='checkbox']")
      $yearDay.each(function(i, e) {
        if ($(e).is(':checked')) {
        } else {
          yearDayAllCheck = false
        }
      })
      if (yearDayAllCheck) {
        $(event)
          .find(".year input[type='checkbox']")
          .prop('checked', true)
        $(event).attr('data-check', 'true')
      } else {
        $(event)
          .find(".year input[type='checkbox']")
          .removeAttr('checked')
        $(event).attr('data-check', 'false')
      }
    })
  })

  //清除筛选
  $('#luckysheet-filter-initial').click(function() {
    if (!checkProtectionAuthorityNormal(Store.currentSheetIndex, 'filter')) {
      return
    }

    $('#luckysheet-filter-menu .luckysheet-filter-selected-input')
      .hide()
      .find('input')
      .val()
    $('#luckysheet-filter-selected span')
      .data('type', '0')
      .data('type', null)
      .text(locale_filter.conditionNone)

    let redo = {}
    redo['type'] = 'datachangeAll_filter_clear'
    redo['sheetIndex'] = Store.currentSheetIndex

    redo['config'] = $.extend(true, {}, Store.config)
    Store.config['rowhidden'] = {}
    redo['curconfig'] = $.extend(true, {}, Store.config)

    redo['filter_save'] = $.extend(true, {}, Store.luckysheet_filter_save)

    let optiongroups = []
    $(
      '#luckysheet-filter-options-sheet' +
        Store.currentSheetIndex +
        ' .luckysheet-filter-options'
    ).each(function() {
      let $t = $(this)

      let optionstate = $t.hasClass('luckysheet-filter-options-active')
      let rowhidden = json.parseJsonParm($t.data('rowhidden'))
      let caljs = json.parseJsonParm($t.data('caljs'))

      optiongroups.push({
        optionstate: optionstate,
        rowhidden: rowhidden,
        caljs: caljs,
        str: $t.data('str'),
        edr: $t.data('edr'),
        cindex: $t.data('cindex'),
        stc: $t.data('stc'),
        edc: $t.data('edc'),
      })
    })
    redo['optiongroups'] = optiongroups

    Store.jfundo.length = 0
    Store.jfredo.push(redo)

    $(
      '#luckysheet-filter-selected-sheet' +
        Store.currentSheetIndex +
        ', #luckysheet-filter-options-sheet' +
        Store.currentSheetIndex
    ).remove()
    $('#luckysheet-filter-menu, #luckysheet-filter-submenu').hide()

    //清除筛选发送给后台
    Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].filter = null
    Store.luckysheetfile[
      getSheetIndex(Store.currentSheetIndex)
    ].filter_select = null

    server.saveParam('fsc', Store.currentSheetIndex, null)

    //config
    Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config =
      Store.config

    server.saveParam('cg', Store.currentSheetIndex, {}, { k: 'rowhidden' })

    //行高、列宽 刷新
    jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length)
  })

  //按照值进行筛选
  $('#luckysheet-filter-byvalue-input').on('input propertychange', function() {
    let v = $(this)
      .val()
      .toString()
    $(
      '#luckysheet-filter-byvalue-select .ListBox .luckysheet-mousedown-cancel'
    ).show()

    if (v != '') {
      $(
        "#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']"
      ).each(function(i, e) {
        if ($(e).closest('.day').length > 0) {
          let day = $(e)
            .siblings('label')
            .text()
            .toString()
          let month = $(e)
            .closest('.monthBox')
            .find('.month label')
            .text()
            .toString()
          let year = $(e)
            .closest('.yearBox')
            .find('.year label')
            .text()
            .toString()
          let itemV = year + '-' + month + '-' + day

          if (itemV.indexOf(v) == -1) {
            $(e)
              .closest('.day')
              .hide()

            //天 对应的 月份
            let $monthDay = $(e)
              .closest('.dayList')
              .find('.day:visible')
            if ($monthDay.length == 0) {
              $(e)
                .closest('.monthBox')
                .find('.month')
                .hide()
            }

            //天 对应的 年份
            let $yearDay = $(e)
              .closest('.monthList')
              .find('.day:visible')
            if ($yearDay.length == 0) {
              $(e)
                .closest('.yearBox')
                .find('.year')
                .hide()
            }
          }
        }

        if ($(e).closest('.textBox').length > 0) {
          let itemV = $(e)
            .siblings('label')
            .text()
            .toString()

          if (itemV.indexOf(v) == -1) {
            $(e)
              .parents('.textBox')
              .hide()
          }
        }
      })
    }
  })

  //筛选取消
  $('#luckysheet-filter-cancel').click(function() {
    $('#luckysheet-filter-menu, #luckysheet-filter-submenu').hide()
  })

  //筛选 确认
  $('#luckysheet-filter-confirm').click(function() {
    let $menu = $('#luckysheet-filter-menu')
    let st_r = $menu.data('str'),
      ed_r = $menu.data('edr'),
      cindex = $menu.data('cindex'),
      st_c = $menu.data('stc'),
      ed_c = $menu.data('edc')

    let rowhiddenother = {} //其它筛选列的隐藏行
    $(
      '#luckysheet-filter-options-sheet' +
        Store.currentSheetIndex +
        ' .luckysheet-filter-options'
    )
      .not(
        $(
          '#luckysheet-filter-options-sheet' +
            Store.currentSheetIndex +
            ' .luckysheet-filter-options'
        )
          .eq(cindex - st_c)
          .get(0)
      )
      .each(function() {
        let $t = $(this),
          rh = $t.data('rowhidden')

        if (rh == '') {
          return true
        }

        rh = JSON.parse(rh.replace(/\'/g, '"'))

        for (let r in rh) {
          rowhiddenother[r] = 0
        }
      })

    let filterdata = {}
    let rowhidden = {}
    let caljs = {}

    if (
      $('#luckysheet-filter-bycondition')
        .next()
        .is(':visible') &&
      $('#luckysheet-filter-byvalue')
        .next()
        .is(':hidden') &&
      $('#luckysheet-filter-selected span').data('value') != 'null'
    ) {
      let $t = $('#luckysheet-filter-selected span')
      let type = $t.data('type'),
        value = $t.data('value')

      caljs['value'] = value
      caljs['text'] = $t.text()

      if (type == '0') {
        caljs['type'] = '0'
      } else if (type == '2') {
        let $input = $(
          '#luckysheet-filter-menu .luckysheet-filter-selected-input2 input'
        )
        caljs['type'] = '2'
        caljs['value1'] = $input.eq(0).val()
        caljs['value2'] = $input.eq(1).val()
      } else {
        caljs['type'] = '1'
        caljs['value1'] = $(
          '#luckysheet-filter-menu .luckysheet-filter-selected-input'
        )
          .eq(0)
          .find('input')
          .val()
      }

      for (let r = st_r + 1; r <= ed_r; r++) {
        if (r in rowhiddenother) {
          continue
        }

        if (Store.flowdata[r] == null) {
          continue
        }

        let cell = Store.flowdata[r][cindex]

        if (value == 'cellnull') {
          //单元格为空
          if (cell != null && !isRealNull(cell.v)) {
            rowhidden[r] = 0
          }
        } else if (value == 'cellnonull') {
          //单元格有数据
          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          }
        } else if (value == 'textinclude') {
          //文本包含
          let value1 = caljs['value1']

          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          } else {
            if (cell.m.indexOf(value1) == -1) {
              rowhidden[r] = 0
            }
          }
        } else if (value == 'textnotinclude') {
          //文本不包含
          let value1 = caljs['value1']

          if (cell == null || isRealNull(cell.v)) {
          } else {
            if (cell.m.indexOf(value1) > -1) {
              rowhidden[r] = 0
            }
          }
        } else if (value == 'textstart') {
          //文本开头为
          let value1 = caljs['value1'],
            valuelen = value1.length

          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          } else {
            if (cell.m.substr(0, valuelen) != value1) {
              rowhidden[r] = 0
            }
          }
        } else if (value == 'textend') {
          //文本结尾为
          let value1 = caljs['value1'],
            valuelen = value1.length

          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          } else {
            if (
              valuelen > cell.m.length ||
              cell.m.substr(cell.m.length - valuelen, valuelen) != value1
            ) {
              rowhidden[r] = 0
            }
          }
        } else if (value == 'textequal') {
          //文本等于
          let value1 = caljs['value1']

          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          } else {
            if (cell.m != value1) {
              rowhidden[r] = 0
            }
          }
        } else if (value == 'dateequal') {
          //日期等于
          let value1 = genarate(caljs['value1'])[2]

          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          } else if (cell.ct != null && cell.ct.t == 'd') {
            if (parseInt(cell.v) != value1) {
              rowhidden[r] = 0
            }
          } else {
            rowhidden[r] = 0
          }
        } else if (value == 'datelessthan') {
          //日期早于
          let value1 = genarate(caljs['value1'])[2]

          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          } else if (cell.ct != null && cell.ct.t == 'd') {
            if (parseInt(cell.v) >= value1) {
              rowhidden[r] = 0
            }
          } else {
            rowhidden[r] = 0
          }
        } else if (value == 'datemorethan') {
          //日期晚于
          let value1 = genarate(caljs['value1'])[2]

          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          } else if (cell.ct != null && cell.ct.t == 'd') {
            if (parseInt(cell.v) <= value1) {
              rowhidden[r] = 0
            }
          } else {
            rowhidden[r] = 0
          }
        } else if (value == 'morethan') {
          //大于
          let value1 = parseFloat(caljs['value1'])

          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          } else if (cell.ct != null && cell.ct.t == 'n') {
            if (cell.v <= value1) {
              rowhidden[r] = 0
            }
          } else {
            rowhidden[r] = 0
          }
        } else if (value == 'moreequalthan') {
          //大于等于
          let value1 = parseFloat(caljs['value1'])

          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          } else if (cell.ct != null && cell.ct.t == 'n') {
            if (cell.v < value1) {
              rowhidden[r] = 0
            }
          } else {
            rowhidden[r] = 0
          }
        } else if (value == 'lessthan') {
          //小于
          let value1 = parseFloat(caljs['value1'])

          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          } else if (cell.ct != null && cell.ct.t == 'n') {
            if (cell.v >= value1) {
              rowhidden[r] = 0
            }
          } else {
            rowhidden[r] = 0
          }
        } else if (value == 'lessequalthan') {
          //小于等于
          let value1 = parseFloat(caljs['value1'])

          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          } else if (cell.ct != null && cell.ct.t == 'n') {
            if (cell.v > value1) {
              rowhidden[r] = 0
            }
          } else {
            rowhidden[r] = 0
          }
        } else if (value == 'equal') {
          //等于
          let value1 = parseFloat(caljs['value1'])

          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          } else if (cell.ct != null && cell.ct.t == 'n') {
            if (cell.v != value1) {
              rowhidden[r] = 0
            }
          } else {
            rowhidden[r] = 0
          }
        } else if (value == 'noequal') {
          //不等于
          let value1 = parseFloat(caljs['value1'])

          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          } else if (cell.ct != null && cell.ct.t == 'n') {
            if (cell.v == value1) {
              rowhidden[r] = 0
            }
          } else {
            rowhidden[r] = 0
          }
        } else if (value == 'include') {
          //介于
          let value1 = parseFloat(caljs['value1']),
            value2 = parseFloat(caljs['value2'])

          let min, max
          if (value1 < value2) {
            min = value1
            max = value2
          } else {
            max = value1
            min = value2
          }

          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          } else if (cell.ct != null && cell.ct.t == 'n') {
            if (cell.v < min || cell.v > max) {
              rowhidden[r] = 0
            }
          } else {
            rowhidden[r] = 0
          }
        } else if (value == 'noinclude') {
          //不在其中
          let value1 = parseFloat(caljs['value1']),
            value2 = parseFloat(caljs['value2'])

          let min, max
          if (value1 < value2) {
            min = value1
            max = value2
          } else {
            max = value1
            min = value2
          }

          if (cell == null || isRealNull(cell.v)) {
            rowhidden[r] = 0
          } else if (cell.ct != null && cell.ct.t == 'n') {
            if (cell.v >= min && cell.v <= max) {
              rowhidden[r] = 0
            }
          } else {
            rowhidden[r] = 0
          }
        }
      }
    } else {
      $(
        "#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']"
      ).each(function(i, e) {
        if ($(e).is(':visible') && $(e).is(':checked')) {
          return true
        }

        if ($(e).closest('.day').length > 0) {
          let day = $(e)
            .siblings('label')
            .text()
          if (Number(day) < 10) {
            day = '0' + Number(day)
          }

          let month = $(e)
            .closest('.monthBox')
            .find('.month label')
            .text()
            .replace(locale_filter.filiterMonthText, '')
          if (Number(month) < 10) {
            month = '0' + Number(month)
          }

          let year = $(e)
            .closest('.yearBox')
            .find('.year label')
            .text()
            .replace(locale_filter.filiterYearText, '')

          let itemV =
            locale_filter.filterDateFormatTip +
            '#$$$#' +
            year +
            '-' +
            month +
            '-' +
            day

          filterdata[itemV] = '1'
        }

        if ($(e).closest('.textBox').length > 0) {
          let itemV = $(e)
            .closest('.textBox')
            .data('filter')

          filterdata[itemV] = '1'
        }
      })

      for (let r = st_r + 1; r <= ed_r; r++) {
        if (r in rowhiddenother) {
          continue
        }

        if (Store.flowdata[r] == null) {
          continue
        }

        let cell = Store.flowdata[r][cindex]

        let value
        if (cell == null || isRealNull(cell.v)) {
          value = 'null#$$$#null'
        } else if (cell.ct != null && cell.ct.t == 'd') {
          let fmt = update('YYYY-MM-DD', cell.v)
          value = locale_filter.filterDateFormatTip + '#$$$#' + fmt
        } else {
          value = cell.v + '#$$$#' + cell.m
        }

        if (value in filterdata) {
          rowhidden[r] = 0
        }
      }
    }

    let $top = $(
      '#luckysheet-filter-options-sheet' +
        Store.currentSheetIndex +
        ' .luckysheet-filter-options'
    ).eq(cindex - st_c)

    let optionstate =
      $(
        "#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']:visible:checked"
      ).length <
        $(
          "#luckysheet-filter-byvalue-select .ListBox input[type='checkbox']:visible"
        ).length ||
      $('#luckysheet-filter-byvalue-input').val().length > 0 ||
      ($('#luckysheet-filter-bycondition')
        .next()
        .is(':visible') &&
        $('#luckysheet-filter-byvalue')
          .next()
          .is(':hidden') &&
        $('#luckysheet-filter-selected span').data('value') != 'null')

    let rowhiddenall = $.extend(true, rowhiddenother, rowhidden),
      rowhidenPre = json.parseJsonParm($top.data('rowhidden'))

    labelFilterOptionState(
      $top,
      optionstate,
      rowhidden,
      caljs,
      true,
      st_r,
      ed_r,
      cindex,
      st_c,
      ed_c
    )

    let cfg = $.extend(true, {}, Store.config)
    cfg['rowhidden'] = rowhiddenall

    //保存撤销
    if (Store.clearjfundo) {
      let redo = {}
      redo['type'] = 'datachangeAll_filter'
      redo['sheetIndex'] = Store.currentSheetIndex

      redo['config'] = $.extend(true, {}, Store.config)
      redo['curconfig'] = cfg

      redo['optionstate'] = optionstate
      redo['optionsindex'] = cindex - st_c

      redo['rowhidden'] = $.extend(true, {}, rowhidden)
      redo['rowhidenPre'] = $.extend(true, {}, rowhidenPre)

      if (caljs != null) {
        redo['caljs'] = caljs
      }

      Store.jfundo.length = 0
      Store.jfredo.push(redo)
    }

    //config
    Store.config = cfg
    Store.luckysheetfile[getSheetIndex(Store.currentSheetIndex)].config =
      Store.config

    server.saveParam('cg', Store.currentSheetIndex, cfg['rowhidden'], {
      k: 'rowhidden',
    })

    //行高、列宽 刷新
    jfrefreshgrid_rhcw(Store.flowdata.length, Store.flowdata[0].length)

    $('#luckysheet-filter-menu, #luckysheet-filter-submenu').hide()
    cleargridelement()
  })
}

export {
  labelFilterOptionState,
  orderbydatafiler,
  createFilter,
  createFilterOptions,
  initialFilterHandler,
}
